home *** CD-ROM | disk | FTP | other *** search
/ BCI NET 2 / BCI NET 2.iso / archives / programming / source / a2.0bemacs-src.lha / Emacs-19.25 / src / amiga_dump.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-28  |  35.5 KB  |  1,524 lines

  1. #include <exec/types.h>
  2. #include <fcntl.h>
  3. #include <stdio.h>
  4. #include <assert.h>
  5. #include <proto/dos.h>
  6. #include <setjmp.h>
  7. #include <internal/messages.h>
  8. #include "config.h"
  9. #include "lisp.h"
  10. #include "buffer.h"
  11. #include "regex.h"
  12. #include "amiga.h"
  13. #include "dispextern.h"
  14. #include "termchar.h"
  15. #include "paths.h"
  16. #include "frame.h"
  17.  
  18. #ifdef USE_PROTOS
  19. #include "protos.h"
  20. #endif
  21.  
  22. #define RANGE(ptr, s, e) ((char *)ptr >= (char *)s && (char *)ptr < (char *)e)
  23. #define HUNK_POS (VALBITS - 3)
  24. #define HUNK_MASK (7 << HUNK_POS)
  25. #define HUNK_CODE (0 << HUNK_POS)
  26. #define HUNK_DATA (1 << HUNK_POS)
  27. #define HUNK_BSS (2 << HUNK_POS)
  28. #define HUNK_MALLOC (3 << HUNK_POS)
  29. #define HUNK_PURE (4 << HUNK_POS)
  30. #define ARRAY_MARK_FLAG ((MARKBIT >> 1) & ~MARKBIT)
  31.  
  32. void *far first_fn = first_function, *far last_fn = last_function;
  33.  
  34. /* alloc.c */
  35. extern int *pure, puresize;
  36. extern struct gcpro *gcprolist;
  37. extern Lisp_Object *staticvec[];
  38. extern int staticidx;
  39. extern struct cons_block *cons_block;
  40. extern struct Lisp_Cons *cons_free_list;
  41. extern struct Lisp_Vector *all_vectors;
  42. extern struct symbol_block *symbol_block;
  43. extern struct Lisp_Symbol *symbol_free_list;
  44. extern struct marker_block *marker_block;
  45. extern struct Lisp_Marker *marker_free_list;
  46. extern struct interval_block *interval_block;
  47. extern INTERVAL interval_free_list;
  48. struct string_block_head
  49.   {
  50.     struct string_block_head *next, *prev;
  51.     int pos;
  52.   };
  53. struct string_block
  54.   {
  55.     struct string_block *next, *prev;
  56. #if 0 /* not needed */
  57.     int pos;
  58.     char chars[STRING_BLOCK_SIZE];
  59. #endif
  60.   };
  61. extern struct string_block *current_string_block;
  62. extern struct string_block *first_string_block;
  63. extern struct string_block *large_string_blocks;
  64. #ifdef LISP_FLOAT_TYPE
  65. extern struct float_block *float_block;
  66. extern struct Lisp_Float *float_free_list;
  67. #endif /* LISP_FLOAT_TYPE */
  68.  
  69. struct backtrace /* see eval.c or alloc.c */
  70.   {
  71.     struct backtrace *next;
  72.     Lisp_Object *function;
  73.     Lisp_Object *args;    /* Points to vector of args. */
  74.     int nargs;        /* Length of vector.
  75.                If nargs is UNEVALLED, args points to slot holding
  76.                list of unevalled args */
  77.     char evalargs;
  78.     /* Nonzero means call value of debugger when done with this operation. */
  79.     char debug_on_exit;
  80.   };
  81. extern struct backtrace *backtrace_list;
  82. struct catchtag
  83.   {
  84.     Lisp_Object tag;
  85.     Lisp_Object val;
  86.     struct catchtag *next;
  87.     struct gcpro *gcpro;
  88.     jmp_buf jmp;
  89.     struct backtrace *backlist;
  90.     struct handler *handlerlist;
  91.     int lisp_eval_depth;
  92.     int pdlcount;
  93.     int poll_suppress_count;
  94.   };
  95. extern struct catchtag *catchlist;
  96. extern char *stack_copy;
  97.  
  98. extern int *kbd_macro_buffer;
  99. extern char *read_buffer, *chars_wasted, *copybuf;
  100. extern struct minibuf_save_data *minibuf_save_vector;
  101. extern struct re_pattern_buffer searchbuf;
  102. #if 0 /* CHFIXME */
  103. extern int *ILcost, *DLcost, *ILncost, *DLncost;
  104. #endif
  105. #if 0
  106. extern Lisp_Object MouseMap, global_map, Vglobal_map, Vesc_map, Vctl_x_map;
  107. #else
  108. extern Lisp_Object global_map, meta_map, control_x_map;
  109. #endif
  110. extern Lisp_Object selected_window;
  111.  
  112. extern char *callint_argfuns[];
  113.  
  114. /* lread.c/init_obarray variables */
  115. extern Lisp_Object Qvariable_documentation, Vpurify_flag;
  116.  
  117. /* eval.c/init_eval_once variables */
  118. /* specpdl */
  119.  
  120. /* syntax.c/init_syntax_once */
  121. /* */
  122.  
  123. /* window.c variables */
  124. /* */
  125.  
  126.  
  127. /* buffer.c */
  128. /* -> buffer.h */
  129.  
  130. /* dired.c */
  131. extern Lisp_Object Qdirectory_files, Qfile_name_completion,
  132.     Qfile_name_all_completions, Qfile_attributes;
  133.  
  134. /* fileio.c */
  135. extern Lisp_Object Qset_visited_file_modtime;
  136.  
  137. /* process.c */
  138. /* extern Lisp_Object stream_process; CHFIXME activate HAVE_SOCKETS ?*/
  139.  
  140. /* editfns.c */
  141. extern char *message_text;
  142.  
  143. /* regex variables */
  144. typedef unsigned char *fail_stack_elt_t;
  145. typedef struct
  146. {
  147.   fail_stack_elt_t *stack;
  148.   unsigned size;
  149.   unsigned avail;            /* Offset of next open position.  */
  150. } fail_stack_type;
  151. typedef short register_info_type;
  152.  
  153. extern fail_stack_type fail_stack;
  154. extern const char **     regstart, **     regend;
  155. extern const char ** old_regstart, ** old_regend;
  156. extern const char **best_regstart, **best_regend;
  157. extern register_info_type *reg_info; 
  158. extern const char **reg_dummy;
  159. extern void *reg_info_dummy;
  160.  
  161. /* keyboard.c/variables CHFIXME: need to be checked on version change */
  162. #define HEAD_TABLE_SIZE 3
  163. #define SCROLL_BAR_PARTS_SIZE 3
  164. struct event_head {
  165.   Lisp_Object *var;
  166.   char *name;
  167.   Lisp_Object *kind;
  168. };
  169.  
  170. extern struct event_head head_table[];
  171. extern Lisp_Object *scroll_bar_parts[];
  172. extern struct input_event *kbd_fetch_ptr;
  173. extern struct input_event volatile *kbd_store_ptr;
  174.  
  175. /* search.c */
  176. extern struct re_registers search_regs;
  177.  
  178. #if 0
  179. #define DBUG /* dump debug */
  180. #endif
  181.  
  182. static char *dump_error_example[] =
  183. {
  184.     "dump-error-example-1",
  185.     "dump-error-example-2"
  186. };
  187.  
  188. static void cpr() {} /* CHFIXME */
  189.  
  190. static void *dump_malloc(int size)
  191. {
  192.   void *new = malloc(size);
  193.  
  194.   if (!new) no_memory();
  195.  
  196.   return new;
  197. }
  198.  
  199. static void bailout(char *fn)
  200. {
  201.   if (fn) _message("%s isn't a dump file for this version of Emacs, aborting", fn);
  202.   else _message("Dump file isn't for this version of Emacs, aborting");
  203.  
  204.   /* We are in deep trouble, as all our variables are potentially corrupt */
  205.   /* Therefore, no cleanup is possible */
  206.   /* Remove cleanup routines */
  207.   onexit(0);
  208.   /* However, the library & the memory allocation should be ok, so
  209.      we can exit reasonably */
  210.   _fail("Some system resources may have been lost");
  211. }
  212.  
  213. void print_ranges()
  214. {
  215. #if 0
  216.     _message("HUNK_CODE  : %08lx .. %08lx (%08lx)",
  217.          first_fn, last_fn, (char *) last_fn - (char *) first_fn);
  218.     _message("HUNK_DATA  : %08lx .. %08lx (%08lx)",
  219.          &first_data, &last_data, (char *) &last_data - (char *) &first_data);
  220.     _message("HUNK_BSS   : %08lx .. %08lx (%08lx)",
  221.          &first_bss, &last_bss, (char *) &last_bss - (char *) &first_bss);
  222.     _message("HUNK_PURE  : %08lx .. %08lx (%08lx)"
  223.          , pure, (char *)pure + puresize, puresize);
  224.     _message("HUNK_MALLOC: %08lx .. %08lx (%08lx)",
  225.          malloc_hunk, malloc_hunk + malloc_hunk_size, malloc_hunk_size);
  226. #endif
  227. }
  228.  
  229. /*
  230.  * ignore:
  231.  *    stack_bottom, IconBase, last_marked (array), interval_block_index (int)
  232.  *      gcprolist (currently?),
  233.  *    pending (list), returned (list)
  234.  */
  235.  
  236. int
  237. check_ignore(void *x)
  238. {
  239. #ifndef USE_PROTOS
  240.     extern int IconBase, IFFParseBase, interval_block_index, instream, cliphook;
  241. #else
  242.     extern int interval_block_index;
  243. #endif
  244.     
  245.     int ign = 0;
  246.     if((x == (void *) &IconBase)
  247.        || (x == (void *) &stack_bottom)
  248. /*        || (x == (void *) &interval_block_index) */
  249.        || (x == (void *) &pure)
  250.        || (x == (void *) &gcprolist)
  251.        || (x == (void *) &malloc_hunk)
  252.        || (x == (void *) &IFFParseBase)
  253.        || (x == (void *) &instream)
  254.        || (x == (void *) &cbuffer_pos)
  255.        || (x == (void *) &cliphook)
  256.        || (x == (void *) ((int *)&cliphook+1))
  257.        || (x == (void *) ((int *)&cliphook+2))
  258.        || (x == (void *) &specpdl_ptr)
  259.        || (x == (void *) &handlerlist) /* CHFIXME: ok? */
  260.        || (x == (void *) &catchlist) /* CHFIXME: ok? */
  261.        || (x == (void *) &backtrace_list) /* CHFIXME: ok? */
  262.        )
  263.     ign = 1;
  264.     
  265.     return ign;
  266. }
  267.  
  268. /*
  269.  *  test for candidates which may need extra handling on dump
  270.  */
  271. void
  272. check_cand(char *s, void *start, void *end)
  273. {
  274.     unsigned int *ip, *starthit = NULL, *lasthit = NULL;
  275.     unsigned short int *is;
  276.     int range = 0;
  277.     int de = ((unsigned)dump_error_example[0] >> 24);
  278.           
  279. #define FIRST ((char*) &first_data) /* first symbol in data hunk */
  280.  
  281.     for(is = start; (char *)is < (char *)end; is++)
  282.     {
  283.     ip = (unsigned int *) is;
  284.     if((((*ip >> 24) == 0x08)
  285.         || (*ip >> 24) == de)
  286.        && ! check_ignore(ip))
  287.     {
  288.         if(lasthit+1 == ip)
  289.         {
  290.         lasthit++;
  291.         range = 1;
  292.         }
  293.         else
  294.         {
  295.         if(range)
  296.         {
  297.             fprintf(stderr,"%s: 0x%08lx .. 0x%08lx (0x%08lx)\n",
  298.                 s,
  299.                 (char *)starthit-FIRST,
  300.                 (char *)lasthit-FIRST,
  301.                 (char*)lasthit-(char*)starthit);
  302.             range = 0;
  303.         }
  304.         else
  305.         {
  306.             starthit = lasthit = ip;
  307.         }
  308.         }
  309.     }
  310.     else
  311.     {
  312.         if((unsigned short *) lasthit+1 != is)
  313.         {
  314.         if(range)
  315.         {
  316.             fprintf(stderr,"%s: 0x%08lx .. 0x%08lx (0x%08lx)\n",
  317.                 s,
  318.                 (char *)starthit-FIRST,
  319.                 (char *)lasthit-FIRST,
  320.                 (char*)lasthit-(char*)starthit);
  321.         }
  322.         else if(lasthit)
  323.         {
  324.             fprintf(stderr,"%s: 0x%08lx (0x%08lx)\n", s, (char *)lasthit-FIRST, *lasthit);
  325.         }
  326.         range = 0;
  327.         lasthit = NULL;
  328.         }
  329.     }
  330.         
  331.     }
  332.     if(range)
  333.     {
  334.     fprintf(stderr,"%s: 0x%08lx .. 0x%08lx (0x%08lx)\n",
  335.         s,
  336.         (char *)starthit-FIRST,
  337.         (char *)lasthit-FIRST,
  338.         (char*)lasthit-(char*)starthit);
  339.     }
  340.     else if(lasthit)
  341.     {
  342.     fprintf(stderr,"%s: 0x%08lx\n (0x%08ls)", s, (char *)lasthit-FIRST, *lasthit);
  343.     }
  344. }
  345.  
  346. void
  347. check_cands(void)
  348. {
  349.     fprintf(stderr,"Possible candidates for FAR or amiga_dump\n");
  350.     check_cand("DATA", &first_data, &last_data);
  351.     check_cand("BSS ", &first_bss, &last_bss);
  352. }
  353.     
  354.  
  355. #ifdef DBUG
  356. static int mcol = 0;
  357. static int mrow = 0;
  358. static FILE *mfile;
  359. static char spaces[] = "                                                                                                                                                                   ";
  360. static mtresh = 0;
  361. void MInit(char *s)
  362. {
  363.     mcol = 0;
  364.     mrow = 0;
  365.     mtresh = 0;
  366.     mfile = fopen(s,"a");
  367.     fprintf(mfile,"\n***START***\n");
  368. }
  369. void MClean()
  370. {
  371.     fprintf(mfile,"\n**END**\n");
  372.     fclose(mfile);
  373. }
  374. #define P(x)
  375. void MEnter(char *s)
  376. {
  377.     if(mtresh > 100) return;
  378. #if 0
  379.     fwrite(spaces, mcol, 1, mfile);
  380. #endif
  381.     fprintf(mfile, "(%d) %s\n", mcol, s);
  382.     mcol += 1;
  383. }
  384. void  M(char *s)
  385. {
  386.     if(mtresh > 100) return;
  387.     mtresh++;
  388. #if 0
  389.     if(mcol)
  390.     fwrite(spaces, mcol, 1, mfile);
  391. #endif
  392.     fprintf(mfile, "(%d) %s\n", mcol, s);
  393. }
  394. void MLeave(char *s)
  395. {
  396.     if(mtresh > 100) return;
  397.  
  398.     mcol -= 1;
  399. #if 0
  400.     if(mcol)
  401.     fwrite(spaces, mcol, 1, mfile);
  402. #endif
  403.     fprintf(mfile, "(%d) %s\n", mcol, s);
  404. }
  405. #else
  406. #define MInit(x)
  407. #define MClean()
  408. #define MEnter(x)
  409. #define M(x)
  410. #define P(x)
  411. #define MLeave(x)
  412. #endif
  413.  
  414. static void *hunk_pointer(void *ptr)
  415. {
  416.     if (!ptr)
  417.     {
  418.     P("P0");
  419.     return ptr;
  420.     }
  421.  
  422. #if 1 /* CHFIXME */
  423.     if(RANGE(ptr, first_fn, last_fn) && ((char *)ptr - (char *)first_fn) == 0x21c)
  424.     cpr();
  425. #endif
  426.     
  427.     if (RANGE(ptr, first_fn, last_fn))
  428.     {
  429.     P("PC");
  430.     return (void *)(HUNK_CODE | (char *)ptr - (char *)first_fn);
  431.     }
  432.     else if (RANGE(ptr, &first_data, &last_data))
  433.     {
  434.     P("PD");
  435.     return (void *)(HUNK_DATA | (char *)ptr - (char *)&first_data);
  436.     }
  437.     else if (RANGE(ptr, &first_bss, &last_bss))
  438.     {
  439.     P("PB");
  440.     return (void *)(HUNK_BSS | (char *)ptr - (char *)&first_bss);
  441.     }
  442.     else if (RANGE(ptr, malloc_hunk, malloc_hunk + malloc_hunk_size))
  443.     {
  444.     P("PM");
  445.     return (void *)(HUNK_MALLOC | (char *)ptr - malloc_hunk);
  446.     }
  447.     else if (RANGE(ptr, pure, (char *)pure + puresize))
  448.     {
  449.     P("PP");
  450.     return (void *)(HUNK_PURE | (char *)ptr - (char *)pure);
  451.     }
  452.     else
  453.     {
  454.     _message("hunk_pointer: cannot locate pointer 0x%08lx", ptr);
  455.     print_ranges();
  456.     bailout(0);
  457.     }
  458. }
  459.  
  460. static Lisp_Object hunk_lispptr(Lisp_Object *objptr, Lisp_Object val)
  461. {
  462.     int type = val & ~VALMASK;
  463.     void *ptr = (void *)XPNTR(val);
  464.  
  465. #if 1 /* CHFIXME */
  466.     if(RANGE(ptr, first_fn, last_fn) && ((char *)ptr - (char *)first_fn) == 0x21c)
  467.     cpr();
  468. #endif
  469.     
  470.     if (RANGE(ptr, first_fn, last_fn))
  471.     {
  472.     M("LC");
  473.     return type | HUNK_CODE | (char *)ptr - (char *)first_fn;
  474.     }
  475.     else if (RANGE(ptr, &first_data, &last_data))
  476.     {
  477.     M("LD");
  478.     return type | HUNK_DATA | (char *)ptr - (char *)&first_data;
  479.     }
  480.     else if (RANGE(ptr, &first_bss, &last_bss))
  481.     {
  482.     M("LB");
  483.     return type | HUNK_BSS | (char *)ptr - (char *)&first_bss;
  484.     }
  485.     else if (RANGE(ptr, pure, (char *)pure + puresize))
  486.     {
  487.     M("LP");
  488.     return type | HUNK_PURE | (char *)ptr - (char *)pure;
  489.     }
  490.     else if (RANGE(ptr, malloc_hunk, malloc_hunk + malloc_hunk_size))
  491.     {
  492.     M("LM");
  493.     return type | HUNK_MALLOC | (char *)ptr - malloc_hunk;
  494.     }
  495.     else 
  496.     {
  497.     _message("hunk_pointer: cannot locate pointer 0x%08lx", ptr);
  498.     print_ranges();
  499.     bailout(0);
  500.     }
  501. }
  502.  
  503. static void patch_pointers ();
  504.  
  505. static void patch_buffer (buf)
  506.      Lisp_Object buf;
  507. {
  508.   Lisp_Object tem;
  509.   register struct buffer *buffer = XBUFFER (buf);
  510.   register Lisp_Object *ptr;
  511.  
  512.   buffer->text.beg = hunk_pointer (buffer->text.beg);
  513.   patch_pointers (&buffer->markers);
  514.  
  515.   /* This is the buffer's markbit */
  516.   patch_pointers (&buffer->name);
  517.   assert(!XMARKBIT(&buffer->name)); /* CHFIXME */
  518.   XMARK (buffer->name);
  519.  
  520.   for (ptr = &buffer->name + 1;
  521.        (char *)ptr < (char *)buffer + sizeof (struct buffer);
  522.        ptr++)
  523.     patch_pointers (ptr);
  524. }
  525.  
  526. static void patch_pointers (objptr)
  527.      Lisp_Object *objptr;
  528. {
  529.   register Lisp_Object obj;
  530.  
  531.   MEnter("O+");
  532.  loop:
  533.   obj = *objptr;
  534.  
  535.  loop2:
  536.   XUNMARK (obj);
  537.  
  538.   switch (XGCTYPE (obj))
  539.     {
  540.     case Lisp_String:
  541.     M("O1");
  542.     /* CHIXME */
  543.       {
  544.     register struct Lisp_String *ptr = XSTRING (obj);
  545.  
  546.     if (ptr->size & MARKBIT)
  547.       /* A large string. */
  548.         _message("Lisp_String case: large_string found!");
  549.       }
  550.       *objptr = hunk_lispptr(objptr, *objptr);
  551.       break;
  552.  
  553.     case Lisp_Vector:
  554.     case Lisp_Window:
  555.     case Lisp_Process:
  556.     case Lisp_Window_Configuration:
  557. M("O2");
  558.       *objptr = hunk_lispptr(objptr, *objptr);
  559.       {
  560.     register struct Lisp_Vector *ptr = XVECTOR (obj);
  561.     register int size = ptr->size;
  562.     struct Lisp_Vector *volatile ptr1 = ptr; /* CHFIXME */
  563.     register int i;
  564.  
  565.     if (size & ARRAY_MARK_FLAG) break;   /* Already marked */
  566.     ptr->size |= ARRAY_MARK_FLAG; /* Else mark it */
  567.     for (i = 0; i < size; i++)     /* and then mark its elements */
  568.       patch_pointers (&ptr1->contents[i]);
  569.       }
  570.       break;
  571.  
  572.     case Lisp_Compiled: /* similar to vector but avoid some recursion */
  573.     M("O3");
  574.       *objptr = hunk_lispptr(objptr, *objptr);
  575.       {
  576.     register struct Lisp_Vector *ptr = XVECTOR (obj);
  577.     register int size = ptr->size;
  578.     struct Lisp_Vector *volatile ptr1 = ptr; /* CHFIXME */
  579.     register int i;
  580.  
  581.     if (size & ARRAY_MARK_FLAG) break;   /* Already marked */
  582.     ptr->size |= ARRAY_MARK_FLAG; /* Else mark it */
  583.     for (i = 0; i < size; i++)     /* and then mark its elements */
  584.         if (i != COMPILED_CONSTANTS)
  585.         patch_pointers (&ptr1->contents[i]);
  586.     objptr = &ptr1->contents[COMPILED_CONSTANTS];
  587.  
  588.     goto loop;
  589.       }
  590.       break;
  591.  
  592.     case Lisp_Symbol:
  593.     M("O4");
  594.       *objptr = hunk_lispptr(objptr, *objptr);
  595.       {
  596.     register struct Lisp_Symbol * volatile ptr = XSYMBOL (obj);
  597.     struct Lisp_Symbol *ptrx;
  598.  
  599.     if (XMARKBIT (ptr->plist)) break;
  600.     XMARK (ptr->plist);
  601.     patch_pointers ((Lisp_Object *) &ptr->value);
  602.     patch_pointers (&ptr->function);
  603.     patch_pointers (&ptr->plist);
  604.     XSETTYPE (*(Lisp_Object *) &ptr->name, Lisp_String);
  605.     patch_pointers ((Lisp_Object *) &ptr->name);
  606.     objptr = (Lisp_Object *)&ptr->next;
  607.     ptr = ptr->next;
  608.     if (ptr)
  609.       {
  610.         ptrx = ptr;        /* Use pf ptrx avoids compiler bug on Sun */
  611.         XSETSYMBOL (obj, ptrx);
  612.         /* We can't goto loop here because *objptr doesn't contain an
  613.            actual Lisp_Object with valid datatype field.  */
  614.  
  615.         goto loop2;
  616.       }
  617.       }
  618.       break;
  619.  
  620.     case Lisp_Marker:
  621.     M("O5");
  622.     {
  623.     struct Lisp_Marker *ptr = XMARKER (obj);
  624.  
  625.     *objptr = hunk_lispptr(objptr, *objptr);
  626.     if (XMARKBIT (ptr->chain)) break;
  627.     XMARK (ptr->chain);
  628.     ptr->buffer = hunk_pointer (ptr->buffer);
  629.     patch_pointers (&ptr->chain);
  630.     break;
  631.     }
  632.  
  633.     case Lisp_Cons:
  634.     case Lisp_Buffer_Local_Value:
  635.     case Lisp_Some_Buffer_Local_Value:
  636.     M("O6");
  637.       *objptr = hunk_lispptr(objptr, *objptr);
  638.       {
  639.     register struct Lisp_Cons *ptr = XCONS (obj);
  640.     if (XMARKBIT (ptr->car)) break;
  641.     XMARK (ptr->car);
  642.     patch_pointers (&ptr->car);
  643.     objptr = &XCONS (obj)->cdr;
  644.     goto loop;
  645.       }
  646.  
  647.     case Lisp_Buffer:
  648.     M("O7");
  649.       *objptr = hunk_lispptr(objptr, *objptr);
  650.       if (!XMARKBIT (XBUFFER (obj)->name))
  651.     patch_buffer (obj);
  652.       break;
  653.  
  654.     case Lisp_Subr: 
  655.     M("O8");
  656.     {
  657.     struct Lisp_Subr *subr = XSUBR(obj);
  658.  
  659.     *objptr = hunk_lispptr(objptr, *objptr);
  660.     if (subr->min_args & 0x8000) break;
  661.     subr->min_args |= 0x8000;
  662.     subr->function = hunk_pointer(subr->function);
  663.     subr->symbol_name = hunk_pointer(subr->symbol_name);
  664.     subr->prompt = hunk_pointer(subr->prompt);
  665.     if ((long)subr->doc >= 0) /* Make sure that not a doc offset */
  666.         subr->doc = hunk_pointer(subr->doc);
  667.     break;
  668.     }
  669.  
  670.     case Lisp_Int:
  671.     case Lisp_Void:
  672.     case Lisp_Buffer_Objfwd: break;
  673.  
  674.     case Lisp_Intfwd:
  675.     case Lisp_Boolfwd:
  676.     case Lisp_Objfwd:
  677.     case Lisp_Internal_Stream:
  678.       M("O9");
  679.       *objptr = hunk_lispptr(objptr, *objptr);
  680.     /* Don't bother with Lisp_Buffer_Objfwd,
  681.        since all markable slots in current buffer marked anyway.  */
  682.     /* Don't need to do Lisp_Objfwd, since the places they point
  683.        are protected with staticpro.  */
  684.       break;
  685.  
  686. #ifdef LISP_FLOAT_TYPE
  687.     case Lisp_Float:
  688.       M("OA");
  689.       *objptr = hunk_lispptr(objptr, *objptr);
  690.       XMARK (XFLOAT (obj)->type);
  691.       break;
  692. #endif /* LISP_FLOAT_TYPE */
  693.     
  694.     default:
  695.       _message("patch_pointers: unknown XGCTYPE (obj): %ld", XGCTYPE (obj));
  696.       abort ();
  697.     }
  698.   MLeave("O-");
  699. }
  700.  
  701. static void patch_chain(void **ptr, int offset)
  702. {
  703.     while (*ptr)
  704.     {
  705.     void **next = (void **)((char *)*ptr + offset);
  706.  
  707.     *ptr = hunk_pointer(*ptr);
  708.     ptr = next;
  709.     }
  710. }
  711.  
  712. #define HUNK_LISPPTR(a) a = hunk_lispptr(&a,a)
  713. #define HUNK_PTR(a) a = hunk_pointer(a)
  714.  
  715. static void patch(void)
  716. {
  717.     Lisp_Object LO;
  718.     int i;
  719.     struct string_block *sptr;
  720.     struct buffer *bptr;
  721.     struct mem_header *mem;
  722.     struct backtrace *backlist;
  723.     struct catchtag *catch;
  724.     
  725.     MInit("MLOG.patch");
  726.     print_ranges(); /* CHFIXME */
  727.  
  728. #ifdef DBUG
  729.     i = 0;
  730. #else
  731.     for (i = 0; i < staticidx; i++)
  732. #endif
  733.     {
  734.     if (!XMARKBIT(*staticvec[i]))
  735.     {
  736.         patch_pointers(staticvec[i]);
  737.         XMARK(*staticvec[i]);
  738.     }
  739.     staticvec[i] = hunk_pointer(staticvec[i]);
  740.     }
  741. #ifndef DBUG
  742.     /* Patch all the pointers normally used before a dump ! */
  743.     patch_chain((void **)&cons_block, 0);
  744.     patch_chain((void **)&cons_free_list, 0);
  745.  
  746.     patch_chain((void **)&all_vectors, 4);
  747.  
  748.     patch_chain((void **)&symbol_block, 0);
  749.     patch_chain((void **)&symbol_free_list, 4);
  750.  
  751.     patch_chain((void **)&marker_block, 0);
  752.     patch_chain((void **)&marker_free_list, 4);
  753.  
  754.     patch_chain((void **)&interval_block, 0);
  755.     patch_chain((void **)&interval_free_list, 4*sizeof(long));
  756.         
  757.     /* Strings are lots of fun */
  758.     patch_chain((void **)&large_string_blocks, 0);
  759.     sptr = first_string_block;
  760.     while (sptr)
  761.     {
  762.     struct string_block *next = sptr->next;
  763.  
  764.     if (sptr->next) HUNK_PTR(sptr->next);
  765.     if (sptr->prev) HUNK_PTR(sptr->prev);
  766.     sptr = next;
  767.     }
  768.     HUNK_PTR(first_string_block);
  769.     HUNK_PTR(current_string_block);
  770.  
  771.     /* More fun with buffers */
  772.     bptr = all_buffers;
  773.     if (bptr)
  774.     {
  775.     while (bptr->next)
  776.     {
  777.         struct buffer *next = bptr->next;
  778.  
  779.         HUNK_PTR(bptr->next);
  780.         bptr = next;
  781.     }
  782.     }
  783.     HUNK_PTR(all_buffers);
  784.     HUNK_PTR(current_buffer);
  785.  
  786. #ifdef LISP_FLOAT_TYPE
  787.     patch_chain((void **) &float_block, 0);
  788.     patch_chain((void **) &float_free_list, 0);
  789. #endif /* LISP_FLOAT_TYPE */
  790.  
  791. #if 0 /* CHFIXME needed ? */
  792.     /* even more fun with 19.25 backtrace */
  793.     for (backlist = backtrace_list; backlist; )
  794.     {
  795.       struct backtrace *next = backlist->next;
  796.       
  797.       if (!XMARKBIT (*backlist->function))
  798.     {
  799.       patch_pointers(backlist->function);
  800.       XMARK (*backlist->function);
  801.     }
  802.       if (backlist->nargs == UNEVALLED || backlist->nargs == MANY)
  803.     i = 0;
  804.       else
  805.     i = backlist->nargs - 1;
  806.       for (; i >= 0; i--)
  807.     if (!XMARKBIT (backlist->args[i]))
  808.       {
  809.         patch_pointers(&backlist->args[i]);
  810.         XMARK (backlist->args[i]);
  811.       }
  812.       if(backlist->next) HUNK_PTR(backlist->next);
  813.       backlist = next;
  814.     }  
  815.     HUNK_PTR(backtrace_list);
  816.  
  817.     for (catch = catchlist; catch;)
  818.     {
  819.       struct catchtag *next = catch->next;
  820.     
  821.       patch_pointers (&catch->tag);
  822.       patch_pointers (&catch->val);
  823.       HUNK_PTR(catch->backlist);
  824.       HUNK_PTR(catch->handlerlist);
  825.  
  826.       if(catch->next) HUNK_PTR(catch->next);
  827.       catch = next;
  828.     }
  829.     HUNK_PTR(catchlist);
  830. #endif
  831.     
  832. /*     HUNK_PTR(gcprolist); CHFIXME*/
  833.     HUNK_PTR(stack_copy);
  834.  
  835.     HUNK_PTR(kbd_macro_buffer);
  836.     HUNK_PTR(minibuf_save_vector);
  837.     HUNK_PTR(searchbuf.buffer);
  838.     HUNK_PTR(searchbuf.fastmap);
  839.     HUNK_PTR(specpdl);
  840.     HUNK_PTR(read_buffer);
  841.     
  842. #if 0 /* CHFIXME */
  843.     MouseMap = hunk_lispptr(&MouseMap, MouseMap);
  844. #endif
  845.     HUNK_LISPPTR( current_global_map );
  846.     HUNK_LISPPTR( global_map );
  847.     HUNK_LISPPTR( meta_map );
  848.     HUNK_LISPPTR( control_x_map );
  849.  
  850.     HUNK_LISPPTR( selected_window );
  851.  
  852.     HUNK_LISPPTR( Qvariable_documentation );
  853.  
  854. #ifndef MULTI_FRAME
  855.     /* CHFIXME: use makro */
  856.     HUNK_LISPPTR( the_only_frame.root_window );
  857. #else
  858.     you lose;
  859. #endif
  860.     
  861.     mem = free_list;
  862.     HUNK_PTR( free_list );
  863.     while (mem)
  864.     {
  865.     struct mem_header *next = mem->next;
  866.  
  867.     HUNK_PTR( mem->prev );
  868.     HUNK_PTR( mem->next );
  869.     mem = next;
  870.     }
  871.  
  872.     for (i = 0; i <= 4; i++)
  873.     HUNK_PTR( callint_argfuns[i] );
  874.  
  875.     HUNK_PTR( fail_stack.stack );
  876.     HUNK_PTR( regstart );
  877.     HUNK_PTR( regend );
  878.     HUNK_PTR( old_regstart );
  879.     HUNK_PTR( old_regend );
  880.     HUNK_PTR( best_regstart );
  881.     HUNK_PTR( best_regend );
  882.     HUNK_PTR( reg_info );
  883.     HUNK_PTR( reg_dummy );
  884.     HUNK_PTR( reg_info_dummy );
  885.     
  886.     for(i = 0; i < HEAD_TABLE_SIZE; i++)
  887.     {
  888.     HUNK_PTR( head_table[i].var  );
  889.     HUNK_PTR( head_table[i].name );
  890.     HUNK_PTR( head_table[i].kind );
  891.     }
  892.     for(i = 0; i < SCROLL_BAR_PARTS_SIZE; i++)
  893.     {
  894.     HUNK_PTR( scroll_bar_parts[i] );
  895.     }
  896.     HUNK_PTR(kbd_fetch_ptr);
  897.     HUNK_PTR(kbd_store_ptr);
  898.     XSET(LO, Lisp_Buffer, &buffer_local_types);
  899.     patch_buffer(LO);
  900.     
  901.     HUNK_LISPPTR(Qdirectory_files);
  902.     HUNK_LISPPTR(Qfile_name_completion);
  903.     HUNK_LISPPTR(Qfile_name_all_completions);
  904.     HUNK_LISPPTR(Qfile_attributes);
  905.     HUNK_LISPPTR(Qset_visited_file_modtime);
  906. /*    HUNK_LISPPTR(stream_process);*/
  907.  
  908.     HUNK_PTR(message_text);
  909.  
  910.     /* search.c */
  911.     HUNK_PTR(search_regs.start);
  912.     HUNK_PTR(search_regs.end);
  913. #endif
  914.     MClean();
  915.     check_cands();
  916. }
  917.  
  918. static dump(char *fn)
  919. {
  920.     BPTR fd;
  921.     long size;
  922.  
  923.     fd = Open(fn, MODE_NEWFILE);
  924.     if (!fd)
  925.       {
  926.         static void unpatch(void);
  927.  
  928.         unpatch();
  929.         _fail("emacs hasn't been dumped (%s missing)", fn);
  930.       }
  931.  
  932.     Write(fd, (char *)&puresize, sizeof puresize);
  933.     Write(fd, (char *)&malloc_hunk_size, sizeof malloc_hunk_size);
  934.     Write(fd, (char *)&first_data, (char *)&last_data - (char *)&first_data);
  935.     Write(fd, (char *)&first_bss, (char *)&last_bss - (char *)&first_bss);
  936.     Write(fd, (char *)pure, puresize);
  937.     Write(fd, (char *)malloc_hunk, malloc_hunk_size);
  938.     Write(fd, (char *)&staticidx, sizeof staticidx);
  939.     Write(fd, (char *)staticvec, staticidx * sizeof(Lisp_Object *));
  940.     size = (char *)last_fn - (char *)first_fn;
  941.     Write(fd, (char *)&size, sizeof size);
  942.  
  943.     Close(fd);
  944. }
  945.  
  946. static void *make_pointer(void *ptr)
  947. {
  948.     int hunk = (long)ptr & HUNK_MASK;
  949.     int offset = (long)ptr & (VALMASK & ~HUNK_MASK);
  950.  
  951.     if (!ptr)
  952.     {
  953.     P("P0");
  954.     return 0;
  955.     }
  956.  
  957.     if (hunk == HUNK_CODE)
  958.     {
  959.     P("PC");
  960.     return (char *)first_fn + offset;
  961.     }
  962.     if (hunk == HUNK_DATA)
  963.     {
  964.     P("PD");
  965.     return (char *)&first_data + offset;
  966.     }
  967.     if (hunk == HUNK_BSS)
  968.     {
  969.     P("PB");
  970.     return (char *)&first_bss + offset;
  971.     }
  972.     if (hunk == HUNK_PURE)
  973.     {
  974.     P("PP");
  975.     return (char *)pure + offset;
  976.     }
  977.     if (hunk == HUNK_MALLOC)
  978.     {
  979.     P("PM");
  980.     return malloc_hunk + offset;
  981.     }
  982.     assert(0);
  983. }
  984.  
  985. static Lisp_Object make_lispptr(Lisp_Object *objptr, Lisp_Object obj)
  986. {
  987.     long val = XUINT(obj);
  988.     int hunk = val & HUNK_MASK;
  989.     int offset = val & ~HUNK_MASK;
  990.     char *ptr;
  991.  
  992.     assert(obj); /* CHFIXME */
  993.     if (hunk == HUNK_CODE)
  994.     {
  995.     M("LC");
  996.     ptr = (char *)first_fn + offset;
  997.     }
  998.     else if (hunk == HUNK_DATA)
  999.     {
  1000.     M("LD");
  1001.     ptr = (char *)&first_data + offset;
  1002.     }
  1003.     else if (hunk == HUNK_BSS)
  1004.     {
  1005.     M("LB");
  1006.     ptr = (char *)&first_bss + offset;
  1007.     }
  1008.     else if (hunk == HUNK_PURE)
  1009.     {
  1010.     M("LP");
  1011.     ptr = (char *)pure + offset;
  1012.     } 
  1013.     else if (hunk == HUNK_MALLOC)
  1014.     {
  1015.     M("LM");
  1016.     ptr = malloc_hunk + offset;
  1017.     }
  1018.     else assert(0);
  1019.  
  1020.     assert((int) ptr > 0); /* CHFIXME */
  1021.     OXSETPNTR(obj, (long)ptr); /* CHFIXME */
  1022.     return obj;
  1023. }
  1024.  
  1025. static void unpatch_pointers ();
  1026.  
  1027. static void unpatch_buffer (buf)
  1028.      Lisp_Object buf;
  1029. {
  1030.   Lisp_Object tem;
  1031.   register struct buffer *buffer = XBUFFER (buf);
  1032.   register Lisp_Object *ptr;
  1033.  
  1034.   buffer->text.beg = make_pointer (buffer->text.beg);
  1035.   unpatch_pointers (&buffer->markers);
  1036.  
  1037.   /* This is the buffer's markbit */
  1038.   XUNMARK (buffer->name);
  1039.   unpatch_pointers (&buffer->name);
  1040.  
  1041.   for (ptr = &buffer->name + 1;
  1042.        (char *)ptr < (char *)buffer + sizeof (struct buffer);
  1043.        ptr++)
  1044.     unpatch_pointers (ptr);
  1045. }
  1046.  
  1047. static void unpatch_pointers (objptr)
  1048.      Lisp_Object *objptr;
  1049. {
  1050.   register Lisp_Object obj;
  1051.   Lisp_Object obj2;
  1052.  
  1053.   MEnter("O+");
  1054.  loop:
  1055.   obj = *objptr;
  1056.  
  1057.  loop2:
  1058.   XUNMARK (obj);
  1059.  
  1060.   switch (XGCTYPE (obj))
  1061.     {
  1062.     case Lisp_String:
  1063.     M("O1");
  1064.       *objptr = make_lispptr(objptr, *objptr);
  1065.       break;
  1066.  
  1067.     case Lisp_Vector:
  1068.     case Lisp_Window:
  1069.     case Lisp_Process:
  1070.     case Lisp_Window_Configuration:
  1071.     M("O2");
  1072.       obj = *objptr = make_lispptr(objptr, *objptr);
  1073.       {
  1074.     register struct Lisp_Vector *ptr = XVECTOR (obj);
  1075.     register int size;
  1076.     struct Lisp_Vector *volatile ptr1 = ptr; /* CHFIXME */
  1077.     register int i;
  1078.  
  1079.     if (!(ptr->size & ARRAY_MARK_FLAG)) break;   /* Already unmarked */
  1080.     size = ptr->size &= ~ARRAY_MARK_FLAG; /* Else unmark it */
  1081.     for (i = 0; i < size; i++)     /* and then unmark its elements */
  1082.       unpatch_pointers (&ptr1->contents[i]);
  1083.       }
  1084.       break;
  1085.  
  1086.     case Lisp_Compiled: /* similar to vector but avoid some recursion */
  1087.     M("O3");
  1088.       obj = *objptr = make_lispptr(objptr, *objptr);
  1089.       {
  1090.     register struct Lisp_Vector *ptr = XVECTOR (obj);
  1091.     register int size = ptr->size;
  1092.     struct Lisp_Vector *volatile ptr1 = ptr; /* CHFIXME */
  1093.     register int i;
  1094.  
  1095.     if (!(size & ARRAY_MARK_FLAG)) break;   /* Already unmarked */
  1096.     size = ptr->size &= ~ARRAY_MARK_FLAG; /* Else unmark it */
  1097.     for (i = 0; i < size; i++)     /* and then mark its elements */
  1098.         if (i != COMPILED_CONSTANTS)
  1099.         unpatch_pointers (&ptr1->contents[i]);
  1100.     objptr = (Lisp_Object *) &ptr1->contents[COMPILED_CONSTANTS];
  1101.  
  1102.     goto loop;
  1103.       }
  1104.       break;
  1105.  
  1106.     case Lisp_Symbol:
  1107.     M("O4");
  1108.     /* due to goto below objptr may not point to object containing
  1109.        SYMBOL type information so let obj care for symbol type */
  1110.       obj2 = *objptr = make_lispptr(objptr, *objptr);
  1111.       {
  1112.     register struct Lisp_Symbol * volatile ptr = XSYMBOL (obj2);
  1113.     struct Lisp_Symbol *ptrx;
  1114.  
  1115.     if (!XMARKBIT (ptr->plist)) break;
  1116.     XUNMARK (ptr->plist);
  1117.     unpatch_pointers ((Lisp_Object *) &ptr->value);
  1118.     unpatch_pointers (&ptr->function);
  1119.     unpatch_pointers (&ptr->plist);
  1120.     unpatch_pointers ((Lisp_Object *) &ptr->name);
  1121.     ptr->name = XSTRING (*(Lisp_Object *)&ptr->name);
  1122.     objptr = (Lisp_Object *)&ptr->next;
  1123.     ptr = ptr->next;
  1124.     if (ptr)
  1125.       {
  1126.         ptrx = ptr;        /* Use pf ptrx avoids compiler bug on Sun */
  1127.         XSETSYMBOL (obj, ptrx);
  1128.  
  1129.         /* We can't goto loop here because *objptr doesn't contain an
  1130.            actual Lisp_Object with valid datatype field.  */
  1131.  
  1132.         goto loop2;
  1133.       }
  1134.       }
  1135.       break;
  1136.  
  1137.     case Lisp_Marker:
  1138.     M("O5");
  1139.      obj = *objptr = make_lispptr(objptr, *objptr);
  1140.       {
  1141.     struct Lisp_Marker *ptr = XMARKER (obj);
  1142.     
  1143.     if (!XMARKBIT (ptr->chain)) break;
  1144.     XUNMARK (ptr->chain);
  1145.     ptr->buffer = make_pointer (ptr->buffer);
  1146.     unpatch_pointers (&ptr->chain);
  1147.       }
  1148.       break;
  1149.  
  1150.     case Lisp_Cons:
  1151.     case Lisp_Buffer_Local_Value:
  1152.     case Lisp_Some_Buffer_Local_Value:
  1153.     M("O6");
  1154.       obj = *objptr = make_lispptr(objptr, *objptr);
  1155.       {
  1156.     register struct Lisp_Cons *ptr = XCONS (obj);
  1157.     if (!XMARKBIT (ptr->car)) break;
  1158.     XUNMARK (ptr->car);
  1159.     unpatch_pointers (&ptr->car);
  1160.     objptr = &ptr->cdr;
  1161.  
  1162.     goto loop;
  1163.       }
  1164.  
  1165.     case Lisp_Buffer:
  1166.     M("O7");
  1167.       obj = *objptr = make_lispptr(objptr, *objptr);
  1168.       if (XMARKBIT (XBUFFER (obj)->name))
  1169.     unpatch_buffer (obj);
  1170.       break;
  1171.  
  1172.     case Lisp_Subr:
  1173.     M("O8");
  1174.     obj = *objptr = make_lispptr(objptr, *objptr);
  1175.     {
  1176.     struct Lisp_Subr *subr = XSUBR(obj);
  1177.     
  1178.     if (!(subr->min_args & 0x8000)) break;
  1179.     subr->min_args &= ~0x8000;
  1180.     subr->function = make_pointer(subr->function);
  1181.     subr->symbol_name = make_pointer(subr->symbol_name);
  1182.     subr->prompt = make_pointer(subr->prompt);
  1183.     if ((long)subr->doc >= 0) /* Make sure that not a doc offset */
  1184.         subr->doc = make_pointer(subr->doc);
  1185.     break;
  1186.     }
  1187.  
  1188.     case Lisp_Int:
  1189.     case Lisp_Void:
  1190.     case Lisp_Buffer_Objfwd: break;
  1191.  
  1192.     case Lisp_Intfwd:
  1193.     case Lisp_Boolfwd:
  1194.     case Lisp_Objfwd:
  1195.     case Lisp_Internal_Stream:
  1196.     M("O9");
  1197.       *objptr = make_lispptr(objptr, *objptr);
  1198.     /* Don't bother with Lisp_Buffer_Objfwd,
  1199.        since all markable slots in current buffer marked anyway.  */
  1200.     /* Don't need to do Lisp_Objfwd, since the places they point
  1201.        are protected with staticpro.  */
  1202.       break;
  1203.  
  1204. #ifdef LISP_FLOAT_TYPE
  1205.     case Lisp_Float:
  1206.       M("OA");
  1207.       obj = *objptr = make_lispptr(objptr, *objptr);
  1208.       XUNMARK (XFLOAT (obj)->type);
  1209.       break;
  1210. #endif /* LISP_FLOAT_TYPE */
  1211.  
  1212.     default:
  1213.       abort ();
  1214.     }
  1215.   MLeave("O-");
  1216. }
  1217.  
  1218. static void unpatch_chain(void **ptr, int offset)
  1219. {
  1220.     while (*ptr)
  1221.     {
  1222.     *ptr = make_pointer(*ptr);
  1223.     ptr = (void **)((char *)*ptr + offset);
  1224.     }
  1225. }
  1226.  
  1227. /* CHFIXME: for all! */
  1228. #define MAKE_LISPPTR(a) a = make_lispptr(&a,a)
  1229. #define MAKE_PTR(a) a = make_pointer(a)
  1230.  
  1231. /* Reconstructs the addresses that were patched */
  1232. static void unpatch(void)
  1233. {
  1234.     Lisp_Object LO;
  1235.     int fd, i;
  1236.     struct string_block *sptr;
  1237.     struct buffer *bptr;
  1238.     struct mem_header *mem;
  1239.     struct backtrace *backlist;
  1240.     struct catchtag *catch;
  1241.  
  1242.     print_ranges(); /* CHFIXME */
  1243.  
  1244.     MInit("MLOG.unpatch");
  1245. #ifdef DBUG
  1246.     i = 0;
  1247. #else
  1248.     for (i = 0; i < staticidx; i++)
  1249. #endif
  1250.     {
  1251.     staticvec[i] = make_pointer(staticvec[i]);
  1252.     if (XMARKBIT(*staticvec[i]))
  1253.     {
  1254.         XUNMARK(*staticvec[i]);
  1255.         unpatch_pointers(staticvec[i]);
  1256.     }
  1257.     }
  1258.  
  1259. #ifndef DBUG
  1260.     /* Unpatch all the pointers normally used before a dump ! */
  1261.     unpatch_chain((void **)&cons_block, 0);
  1262.     unpatch_chain((void **)&cons_free_list, 0);
  1263.  
  1264.     unpatch_chain((void **)&all_vectors, 4);
  1265.  
  1266.     unpatch_chain((void **)&symbol_block, 0);
  1267.     unpatch_chain((void **)&symbol_free_list, 4);
  1268.  
  1269.     unpatch_chain((void **)&marker_block, 0);
  1270.     unpatch_chain((void **)&marker_free_list, 4);
  1271.  
  1272.     unpatch_chain((void **)&interval_block, 0);
  1273.     unpatch_chain((void **)&interval_free_list, 4*sizeof(long));
  1274.         
  1275.     /* Strings are lots of fun */
  1276.     unpatch_chain((void **)&large_string_blocks, 0);
  1277.     sptr = MAKE_PTR(first_string_block);
  1278.     MAKE_PTR(current_string_block);
  1279.     while (sptr)
  1280.     {
  1281.     if (sptr->next) MAKE_PTR(sptr->next);
  1282.     if (sptr->prev) MAKE_PTR(sptr->prev);
  1283.     sptr = sptr->next;
  1284.     }
  1285.  
  1286.     /* More fun with buffers */
  1287.     bptr = MAKE_PTR(all_buffers);
  1288.     if (bptr)
  1289.     {
  1290.     while (bptr->next)
  1291.     {
  1292.         MAKE_PTR(bptr->next);
  1293.         bptr = bptr->next;
  1294.     }
  1295.     }
  1296.     MAKE_PTR(current_buffer);
  1297.  
  1298. #ifdef LISP_FLOAT_TYPE
  1299.     unpatch_chain((void **) &float_block, 0);
  1300.     unpatch_chain((void **) &float_free_list, 0);
  1301. #endif /* LISP_FLOAT_TYPE */
  1302.     
  1303. #if 0 /* CHFIXME needed ? */
  1304.     /* even more fun with 19.25 backtrace */
  1305.     MAKE_PTR(backtrace_list);
  1306.     for (backlist = backtrace_list; backlist; backlist = backlist->next)
  1307.     {
  1308.       if(backlist->next) MAKE_PTR(backlist->next);
  1309.       
  1310.       if (XMARKBIT (*backlist->function))
  1311.     {
  1312.       XUNMARK (*backlist->function);
  1313.       unpatch_pointers(backlist->function);
  1314.     }
  1315.       if (backlist->nargs == UNEVALLED || backlist->nargs == MANY)
  1316.     i = 0;
  1317.       else
  1318.     i = backlist->nargs - 1;
  1319.       for (; i >= 0; i--)
  1320.     if (XMARKBIT (backlist->args[i]))
  1321.       {
  1322.         XUNMARK (backlist->args[i]);
  1323.         unpatch_pointers(&backlist->args[i]);
  1324.       }
  1325.     }  
  1326.  
  1327.     MAKE_PTR(catchlist);
  1328.     for (catch = catchlist; catch; catch = catch->next)
  1329.     {
  1330.       if(catch->next) MAKE_PTR(catch->next);
  1331.     
  1332.       unpatch_pointers (&catch->tag);
  1333.       unpatch_pointers (&catch->val);
  1334.       MAKE_PTR(catch->backlist);
  1335.       MAKE_PTR(catch->handlerlist);
  1336.     }
  1337. #endif
  1338.     
  1339. /*    MAKE_PTR(gcprolist); CHFIXME */
  1340.     MAKE_PTR(stack_copy);
  1341.  
  1342.     MAKE_PTR(kbd_macro_buffer);
  1343.     MAKE_PTR(minibuf_save_vector);
  1344.     MAKE_PTR(searchbuf.buffer);
  1345.     MAKE_PTR(searchbuf.fastmap);
  1346.     MAKE_PTR(specpdl);
  1347.     MAKE_PTR(read_buffer);
  1348.  
  1349. #if 0 /* CHFIXME */
  1350.     MouseMap = make_lispptr(&MouseMap, MouseMap);
  1351. #endif
  1352.     MAKE_LISPPTR(current_global_map);
  1353.     MAKE_LISPPTR(global_map);
  1354.     MAKE_LISPPTR(meta_map);
  1355.     MAKE_LISPPTR(control_x_map);
  1356.  
  1357.     MAKE_LISPPTR(selected_window);
  1358.  
  1359.     MAKE_LISPPTR(Qvariable_documentation);
  1360.  
  1361. #ifndef MULTI_FRAME
  1362.     /* CHFIXME: use makro */
  1363.     MAKE_LISPPTR(the_only_frame.root_window);
  1364. #else
  1365.     you lose;
  1366. #endif
  1367.  
  1368.     MAKE_PTR(free_list);
  1369.     mem = free_list;
  1370.     while (mem)
  1371.     {
  1372.     MAKE_PTR(mem->prev);
  1373.     MAKE_PTR(mem->next);
  1374.     mem = mem->next;
  1375.     }
  1376.  
  1377.     for (i = 0; i <= 4; i++)
  1378.     MAKE_PTR(callint_argfuns[i]);
  1379.  
  1380.     MAKE_PTR(fail_stack.stack);
  1381.     MAKE_PTR(regstart);
  1382.     MAKE_PTR(regend);
  1383.     MAKE_PTR(old_regstart);
  1384.     MAKE_PTR(old_regend);
  1385.     MAKE_PTR(best_regstart);
  1386.     MAKE_PTR(best_regend);
  1387.     MAKE_PTR(reg_info);
  1388.     MAKE_PTR(reg_dummy);
  1389.     MAKE_PTR(reg_info_dummy);
  1390.     
  1391.     for(i = 0; i < HEAD_TABLE_SIZE; i++)
  1392.     {
  1393.     MAKE_PTR(head_table[i].var);
  1394.     MAKE_PTR(head_table[i].name);
  1395.     MAKE_PTR(head_table[i].kind);
  1396.     }
  1397.     for(i = 0; i < SCROLL_BAR_PARTS_SIZE; i++)
  1398.     MAKE_PTR(scroll_bar_parts[i]);
  1399.  
  1400.     MAKE_PTR(kbd_fetch_ptr);
  1401.     MAKE_PTR(kbd_store_ptr);
  1402.  
  1403.     XSET(LO, Lisp_Buffer, &buffer_local_types);
  1404.     unpatch_buffer(LO);
  1405.     
  1406.     MAKE_LISPPTR(Qdirectory_files);
  1407.     MAKE_LISPPTR(Qfile_name_completion);
  1408.     MAKE_LISPPTR(Qfile_name_all_completions);
  1409.     MAKE_LISPPTR(Qfile_attributes);
  1410.     MAKE_LISPPTR(Qset_visited_file_modtime);
  1411. /*    MAKE_LISPPTR(stream_process);*/
  1412.  
  1413.     MAKE_PTR(message_text);
  1414.  
  1415.     /* search.c */
  1416.     MAKE_PTR(search_regs.start);
  1417.     MAKE_PTR(search_regs.end);
  1418. #endif
  1419.     MClean();
  1420. }
  1421.  
  1422. static undump(char *fn)
  1423. {
  1424.   BPTR fd;
  1425.   long code_size;
  1426.   char *_malloc_hunk;
  1427.   int *_pure;
  1428.   /*extern struct Library *FifoBase;
  1429.   struct Library *_FifoBase = FifoBase;*/
  1430.  
  1431.   fd = Open(fn, MODE_OLDFILE);
  1432.   if (!fd) return 0;
  1433.  
  1434.   Read(fd, (char *)&puresize, sizeof puresize);
  1435.   Read(fd, (char *)&malloc_hunk_size, sizeof malloc_hunk_size);
  1436.   _pure = dump_malloc(puresize);
  1437.   _malloc_hunk = dump_malloc(malloc_hunk_size + pre_alloc);
  1438.   Read(fd, (char *)&first_data, (char *)&last_data - (char *)&first_data);
  1439.   Read(fd, (char *)&first_bss, (char *)&last_bss - (char *)&first_bss);
  1440.   Read(fd, (char *)_pure, puresize);
  1441.   Read(fd, (char *)_malloc_hunk, malloc_hunk_size);
  1442.   Read(fd, (char *)&staticidx, sizeof staticidx);
  1443.   Read(fd, (char *)staticvec, staticidx * sizeof(Lisp_Object *));
  1444.   /*FifoBase = _FifoBase;*/
  1445.   if (Read(fd, (char *)&code_size, sizeof code_size) != sizeof code_size ||
  1446.       code_size != (char *)last_fn - (char *)first_fn)
  1447.   {
  1448.       Close(fd);
  1449.       bailout(fn);
  1450.   }
  1451.  
  1452.   Close(fd);
  1453.   malloc_hunk = _malloc_hunk;
  1454.   pure = _pure;
  1455.   return 1;
  1456. }
  1457.  
  1458. void map_out_data(char *fn)
  1459. {
  1460.     if (amiga_initialized) error("You can only dump once !");
  1461.     Fgarbage_collect();
  1462.  
  1463. #if 0 /* CHFIXME */
  1464.     dump("EMACS-DATA.pre");
  1465. #endif
  1466.     patch();
  1467.     dump(fn);
  1468.     unpatch();
  1469. #if 0
  1470.     dump("EMACS-DATA.post");
  1471. #endif
  1472.     amiga_initialized = 1;
  1473. }
  1474.  
  1475. #ifndef MULTI_FRAME
  1476. static struct x_display A_Display;
  1477. #else
  1478. you lose */
  1479. #endif
  1480.  
  1481. void map_in_data(int load)
  1482. {
  1483.     if (load && undump(NAME_DATA))
  1484.     {
  1485.     unpatch();
  1486. #if 0 /*CHFIXME */
  1487.     current_screen = new_screen = temp_screen = 0;
  1488.     message_buf = 0;
  1489. #endif
  1490.     chars_wasted = 0;
  1491.     copybuf = 0;
  1492.     initialized = amiga_initialized = 1;
  1493.     
  1494.     /* CHFIXME: force errors if used but not patched */
  1495.     handlerlist = (void *) -1;
  1496.     catchlist = (void *)-1;
  1497.         backtrace_list = (void *)-1;
  1498. #if 0
  1499.     FRAME_EXTERNAL_MENU_BAR(selected_frame) = 1; /* CHFIXME where to put? */
  1500. #endif
  1501.     }
  1502.     else
  1503.       {
  1504.     malloc_hunk = dump_malloc(malloc_hunk_size + pre_alloc);
  1505.     pure = dump_malloc(puresize);
  1506.       }
  1507. #ifndef MULTI_FRAME
  1508.     FRAME_DISPLAY(selected_frame) = &A_Display;
  1509. #else
  1510.     you lose again.
  1511. #endif
  1512.     amiga_undump_reinit();
  1513. }
  1514.  
  1515. void
  1516. early_init_amiga_dump()
  1517. {
  1518. #ifndef MULTI_FRAME
  1519.     FRAME_DISPLAY(selected_frame) = &A_Display;
  1520. #else
  1521.     you lose again.
  1522. #endif
  1523. }
  1524.